<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>
<body>
    
</body>
<script>
    // ### 组合模式
    // 组合模式，就是把几个构造函数的启动方式组合再一起
    // 然后用一个 ”遥控器“ 进行统一调用
    // 可以理解为就是一个批处理工具

    class Door{
        init(){
            console.log("客户已到家,自动开门");
        }
    }

    class Light{
        init(){
            console.log("自动开灯");
        }
    }

    class Sound{
        init(){
            console.log("播放音乐");
        }
    }

    class Air{
        init(){
            console.log("打开空调");
        }
    }
    // 字面量对象版
    // compose = {
    //     list:[new Door(),new Light()],  // 存储构造函数的实例
    //     add(){ // 添加实例
    //     },
    //     excute(){ // 将存储的实例 依次调用init
    //     }
    // }

    // 构造函数版(clss)
    class Compose{
        // list = [];
        constructor(){
            // this.list = [];  // {list:[]}
            
            this.list = new Set();
        }
        add(instance){
            // this -> 调用此方法的实例化对象
            // this.list.push(instance);
            // 去重处理
            // var s = new Set(this.list);
            // this.list = [...s];

            if(!this.list.has(instance)){
                this.list.add(instance);
            }

            return  this;  // 返回实例化对象本身 可以继续调用add
        }
        delete(instance){
            // var index = this.list.findIndex(item => instance == item);
            // if(index!= -1){
            //     this.list.splice(index,1);
            // } 

            this.list.delete(instance);
            return  this; 
        }        
        excute(){
            // this.list.forEach(instance => instance.init())
            this.list.forEach(instance => instance.init());
        }
    }

    var normalMode = new Compose();

    // 添加需要启动的智能家居
    normalMode.add(new Door());
    normalMode.add(new Light());
    normalMode.add(new Sound());
    normalMode.add(new Air());

    console.log(normalMode);

    normalMode.excute();
    
</script>
</html>